# -*- coding:utf-8 -*- 
import mimetypes
import posixpath
import zlib


class CompressStream:
    
    CHUCK_SIZE = 1024 ** 2 # 1 MB
    
    def __init__(self, fileobj, filename='', level=1):
        
        self._fileobj = fileobj
        self.compressor = zlib.compressobj(level)
        self.decompressor = zlib.decompressobj()
        self._flushed = False
        
    
    def read(self, size):
        if not self._flushed :
            buffer = self._fileobj.read(self.CHUCK_SIZE)
            if not buffer :
                self._flushed = True
                return self.compressor.flush()
            else:
                 return self.compressor.compress(buffer)
        
        return None
    
    
    def write(self, buffer):
        if self._flushed :
            raise IOError('File was flushed, and can not write any more')
        
        to_decompress = self.decompressor.unconsumed_tail + buffer
        output = ''
        while to_decompress:
            decompressed = self.decompressor.decompress(to_decompress)
            if decompressed:
                output += decompressed
                # Look for unconsumed data due to buffer overflow
                to_decompress = self.decompressor.unconsumed_tail
            else:
                to_decompress = None
        
        self._fileobj.write(output)        
        return len(output)
    
    
    def fileno(self):
        return self._fileobj.fileno()
    
    
    @property
    def closed(self):
        return self._fileobj.closed
    
    
    def flush(self):
        remainder = self.decompressor.flush()
        if remainder:
            self._fileobj.write(remainder)
        self._fileobj.flush()
        self._flushed = True
        
    
    def close(self):
        return self._fileobj.close()


if not mimetypes.inited:
        mimetypes.init() # try to read system mime.types

_extensions_map = mimetypes.types_map.copy()
_extensions_map.update({
    '': 'application/octet-stream', # Default
    '.py': 'text/plain',
    '.c': 'text/plain',
    '.h': 'text/plain',
    })
      
    
def guess_type(path):
        """Guess the type of a file.

        Argument is a PATH (a filename).

        Return value is a string of the form type/subtype,
        usable for a MIME Content-type header.

        The default implementation looks the file's extension
        up in the table self.extensions_map, using application/octet-stream
        as a default; however it would be permissible (if
        slow) to look inside the data to make a better guess.

        """

        base, ext = posixpath.splitext(path)
        if ext in _extensions_map:
            return _extensions_map[ext]
        ext = ext.lower()
        if ext in _extensions_map:
            return _extensions_map[ext]
        else:
            return _extensions_map['']

   